#include <stdlib.h>
#include <stdio.h>
#include "myFramework.h"
#include "PostProcess.h"

Image *g_img = NULL;
Texture *g_texture = NULL, *g_texRT = NULL;
RenderTarget *g_renderTarget = NULL;
Mesh *g_model = NULL;
Camera *g_rtCamera = NULL;

APP_MAIN_IMPLEMENTATION(PostProcessDemo)

  void PostProcessDemo::Render2D(double timeElapsed)
{
}

void PostProcessDemo::Render(double timeElapsed)
{
  if(!g_renderTarget)
    return;

  m_renderer->EnableTexture();
  m_renderer->EnableDepthTest();
  //rotate the camera for the fbo rendering
  static float rotate = 0.0f;
  Vec3 pos = Vec3( sinf(rotate)*3, 5, cosf(rotate)*3);
  rotate = (rotate + 0.003);

  //    // render to fbo
  g_renderTarget->Begin();
  g_rtCamera->LookAt(pos, Vec3(0,0,0));
  g_rtCamera->Look();
  m_renderer->Clear(WHITE);

  DrawGrid(BLACK);

  m_renderer->EnableTexture();
  m_renderer->EnableDepthTest();
  g_texture->Begin();

  g_model->Render(timeElapsed);

  g_renderTarget->End();
  //   g_renderTarget->Download("PostProcessDemo.bmp");

  // now render to the real frame buffer
  m_renderer->Clear(WHITE);
  m_camera->Look();

  DrawGrid(BLACK);
  glColor3f(1,1,1);

  m_renderer->EnableTexture();
  m_renderer->EnableDepthTest();
  g_texRT->Begin();

  DrawCube();
}

PostProcessDemo::PostProcessDemo()
  :NATIVE_APP(Vec2(0,0), Vec2(512,512), "PostProcessDemo")
{

}

bool PostProcessDemo::initGraphics(AppBase::GRAPHIC_TYPE type)
{
  if(!NATIVE_APP::initGraphics(type))
    return false;

  // load a texture for model
  g_img = ImageManager::InstanceRef().LoadFromFile("img1", "beaver_256.png");
  g_texture = m_renderer->CreateTexture();
  g_texture->Create(*g_img);

  // create a texture for fbo
  g_texRT = m_renderer->CreateTexture();
  g_texRT->Create(512, 512, PIXEL_R8G8B8A8);

  // create fbo as a render target, and bind a texture to it
  g_renderTarget = m_renderer->CreateRenderTarget();
  g_renderTarget->Create(g_texRT);

  // load a model
  g_model = MeshManager::InstanceRef().LoadObj("model1", "teapot.obj");

  // create a extra camera for fbo
  g_rtCamera = m_renderer->CreateCamera();


  return true;
}

// save fbo to a image while pressing "c"
bool PostProcessDemo::OnKey(unsigned key, bool down)
{
  if(down && key == KEY_C)
  {
    static int count = 0;
    std::stringstream ss;
    ss << "screen" << count++ << ".png";

    Image* imgOutput = ImageManager::InstanceRef().CreateImage(EMPTY_STRING, g_texRT->GetWidth(), g_texRT->GetHeight(), PIXEL_R8G8B8A8);
    g_renderTarget->Download(imgOutput);
    ImageManager::InstanceRef().SaveToFile(imgOutput, ss.str() , IFF_PNG);
  }

  return NATIVE_APP::OnKey(key, down);
}
